{% extends "base.html" %}

{% block title %}概览 - XbyJob{% endblock %}

{% block extra_css %}
<style>
    /* 确保统计卡片文字可见 */
    .stats-card.text-white,
    .stats-card.text-white * {
        color: white !important;
    }
    
    .stats-card.bg-primary,
    .stats-card.bg-success,
    .stats-card.bg-info,
    .stats-card.bg-warning {
        color: white !important;
    }
    
    .stats-card .card-title,
    .stats-card h3,
    .stats-card h5 {
        color: white !important;
    }
    
    /* 优化图标颜色和样式 */
    .stats-card .fas {
        color: rgba(255, 255, 255, 0.9) !important;
        text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
        transition: all 0.3s ease;
    }
    
    .stats-card:hover .fas {
        color: white !important;
        transform: scale(1.1);
    }
    
    /* 为不同背景色的卡片设置更好的图标效果 */
    .stats-card.bg-primary .fas {
        color: rgba(255, 255, 255, 0.95) !important;
    }
    
    .stats-card.bg-success .fas {
        color: rgba(255, 255, 255, 0.95) !important;
    }
    
    .stats-card.bg-info .fas {
        color: rgba(255, 255, 255, 0.95) !important;
    }
    
    .stats-card.bg-warning .fas {
        color: rgba(255, 255, 255, 0.95) !important;
    }
    
    /* 优化卡片整体效果 */
    .stats-card {
        border: none !important;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        transition: all 0.3s ease;
    }
    
    .stats-card:hover {
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
        transform: translateY(-2px);
    }
    
    /* 确保卡片头部文字可见 */
    .card-header h5,
    .card-header h5 i {
        color: #343a40 !important;
    }
    
    /* 确保表格文字可见 */
    .table th,
    .table td {
        color: #343a40 !important;
    }
    
    /* 确保普通卡片内容文字可见 */
    .card-body {
        color: #343a40 !important;
    }
    
    /* 确保加载文字可见 */
    .text-center {
        color: #343a40 !important;
    }
</style>
{% endblock %}

{% block content %}
<div class="py-3">
    <h2><i class="fas fa-tachometer-alt me-2"></i>系统概览</h2>
    
    <!-- 统计卡片 -->
    <div class="row mb-4" id="stats-cards">
        <div class="col-xl-3 col-md-6 mb-3">
            <div class="card stats-card text-white bg-primary">
                <div class="card-body">
                    <div class="d-flex justify-content-between">
                        <div>
                            <h5 class="card-title">总任务数</h5>
                            <h3 id="total-tasks">-</h3>
                        </div>
                        <div class="align-self-center">
                            <i class="fas fa-tasks fa-2x"></i>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        
        <div class="col-xl-3 col-md-6 mb-3">
            <div class="card stats-card text-white bg-success">
                <div class="card-body">
                    <div class="d-flex justify-content-between">
                        <div>
                            <h5 class="card-title">活跃任务</h5>
                            <h3 id="active-tasks">-</h3>
                        </div>
                        <div class="align-self-center">
                            <i class="fas fa-play-circle fa-2x"></i>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        
        <div class="col-xl-3 col-md-6 mb-3">
            <div class="card stats-card text-white bg-info">
                <div class="card-body">
                    <div class="d-flex justify-content-between">
                        <div>
                            <h5 class="card-title">总执行次数</h5>
                            <h3 id="total-executions">-</h3>
                        </div>
                        <div class="align-self-center">
                            <i class="fas fa-history fa-2x"></i>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        
        <div class="col-xl-3 col-md-6 mb-3">
            <div class="card stats-card text-white bg-warning">
                <div class="card-body">
                    <div class="d-flex justify-content-between">
                        <div>
                            <h5 class="card-title">今日执行</h5>
                            <h3 id="today-executions">-</h3>
                        </div>
                        <div class="align-self-center">
                            <i class="fas fa-calendar-day fa-2x"></i>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    
    <div class="row">
        <!-- 执行趋势图 -->
        <div class="col-lg-8 mb-4">
            <div class="card">
                <div class="card-header">
                    <h5><i class="fas fa-chart-line me-2"></i>最近7天执行趋势</h5>
                </div>
                <div class="card-body" style="height: 400px;">
                    <canvas id="executionTrendChart"></canvas>
                </div>
            </div>
        </div>
        
        <!-- 执行状态分布 -->
        <div class="col-lg-4 mb-4">
            <div class="card">
                <div class="card-header">
                    <h5><i class="fas fa-chart-pie me-2"></i>执行状态分布</h5>
                </div>
                <div class="card-body" style="height: 400px;">
                    <canvas id="statusPieChart"></canvas>
                </div>
            </div>
        </div>
    </div>
    
    <div class="row">
        <!-- 最近执行记录 -->
        <div class="col-lg-8 mb-4">
            <div class="card">
                <div class="card-header">
                    <h5><i class="fas fa-history me-2"></i>最近执行记录</h5>
                </div>
                <div class="card-body">
                    <div class="table-responsive">
                        <table class="table table-striped" id="recent-executions-table">
                            <thead>
                                <tr>
                                    <th>任务名称</th>
                                    <th>状态</th>
                                    <th>开始时间</th>
                                    <th>耗时</th>
                                </tr>
                            </thead>
                            <tbody>
                                <tr>
                                    <td colspan="4" class="text-center">加载中...</td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
        
        <!-- 即将执行的任务 -->
        <div class="col-lg-4 mb-4">
            <div class="card">
                <div class="card-header">
                    <h5><i class="fas fa-clock me-2"></i>即将执行</h5>
                </div>
                <div class="card-body">
                    <div id="upcoming-tasks">
                        <div class="text-center">加载中...</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
{% endblock %}

{% block extra_js %}
<script>
$(document).ready(function() {
    console.log('Overview页面初始化');
    
    // 检查用户是否已登录
    console.log('当前用户:', '{{ current_user.username if current_user.is_authenticated else "未登录" }}');
    
    // 如果用户未登录，重定向到登录页面
    {% if not current_user.is_authenticated %}
        console.log('用户未登录，重定向到登录页面');
        window.location.href = '/auth/login';
        return;
    {% endif %}
    
    loadDashboardData();
    
    // 每30秒刷新一次数据
    setInterval(loadDashboardData, 30000);
});

function loadDashboardData() {
    console.log('开始加载 Dashboard 数据...');
    
    fetch('/dashboard/api/stats/dashboard', {
        method: 'GET',
        credentials: 'same-origin',  // 保证携带cookies
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        }
    })
    .then(response => {
        console.log('响应状态:', response.status);
        console.log('响应类型:', response.headers.get('content-type'));
        
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        // 检查响应类型
        const contentType = response.headers.get('content-type');
        if (!contentType || !contentType.includes('application/json')) {
            console.error('收到非-JSON响应:', contentType);
            throw new Error('收到的响应不是JSON格式');
        }
        
        return response.json();
    })
    .then(response => {
        console.log('解析后JSON数据:', response);
        
        if (response && response.success) {
            console.log('数据加载成功，开始更新组件...');
            updateStatsCards(response.data.basic_stats);
            updateExecutionTrendChart(response.data.daily_trend);
            updateStatusPieChart(response.data.status_stats);
            updateRecentExecutions(response.data.recent_executions);
            updateUpcomingTasks(response.data.upcoming_tasks);
            console.log('所有组件更新完毕');
        } else {
            console.error('获取统计数据失败:', response);
            showErrorMessage('加载统计数据失败: ' + (response.message || '未知错误'));
        }
    })
    .catch(error => {
        console.error('加载 Dashboard 数据失败:', error);
        
        // 检查是否为认证问题
        if (error.message.includes('401') || error.message.includes('403')) {
            console.log('认证失败，重定向到登录页面');
            window.location.href = '/auth/login';
            return;
        }
        
        showErrorMessage('网络请求失败，请稍后重试: ' + error.message);
    });
}

function showErrorMessage(message) {
    // 在统计卡片中显示错误信息
    $('.card-body').html(`
        <div class="text-center text-danger">
            <i class="fas fa-exclamation-triangle fa-2x mb-2"></i>
            <p>${message}</p>
            <button class="btn btn-outline-primary btn-sm" onclick="loadDashboardData()">
                <i class="fas fa-sync-alt"></i> 重试
            </button>
        </div>
    `);
}

function updateStatsCards(stats) {
    $('#total-tasks').text(stats.total_tasks);
    $('#active-tasks').text(stats.active_tasks);
    $('#total-executions').text(stats.total_executions);
    $('#today-executions').text(stats.today_executions);
}

function updateExecutionTrendChart(trendData) {
    console.log('更新执行趋势图:', trendData);
    
    if (!trendData || !Array.isArray(trendData) || trendData.length === 0) {
        console.warn('无有趋势数据或数据为空');
        return;
    }
    
    const ctx = document.getElementById('executionTrendChart').getContext('2d');
    
    // 销毁已存在的图表（先检查是否存在且有destroy方法）
    if (window.executionTrendChart && typeof window.executionTrendChart.destroy === 'function') {
        window.executionTrendChart.destroy();
    }
    
    window.executionTrendChart = new Chart(ctx, {
        type: 'line',
        data: {
            labels: trendData.map(d => d.date),
            datasets: [{
                label: '总执行数',
                data: trendData.map(d => d.executions || 0),
                borderColor: 'rgb(54, 162, 235)',
                backgroundColor: 'rgba(54, 162, 235, 0.1)',
                tension: 0.1
            }, {
                label: '成功执行',
                data: trendData.map(d => d.success || 0),
                borderColor: 'rgb(75, 192, 192)',
                backgroundColor: 'rgba(75, 192, 192, 0.1)',
                tension: 0.1
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            scales: {
                y: {
                    beginAtZero: true
                }
            }
        }
    });
    
    console.log('执行趋勿图更新完毕');
}

function updateStatusPieChart(statusStats) {
    console.log('更新状态饱图:', statusStats);
    
    if (!statusStats || typeof statusStats !== 'object') {
        console.warn('无有状态统计数据或数据格式错误');
        return;
    }
    
    const ctx = document.getElementById('statusPieChart').getContext('2d');
    
    // 销毁已存在的图表（先检查是否存在且有destroy方法）
    if (window.statusPieChart && typeof window.statusPieChart.destroy === 'function') {
        window.statusPieChart.destroy();
    }
    
    const statusLabels = {
        'success': '成功',
        'failed': '失败',
        'running': '运行中',
        'pending': '等待中',
        'cancelled': '取消'
    };
    
    const statusColors = {
        'success': '#28a745',
        'failed': '#dc3545',
        'running': '#007bff',
        'pending': '#ffc107',
        'cancelled': '#6c757d'
    };
    
    const labels = [];
    const data = [];
    const colors = [];
    
    for (const [status, count] of Object.entries(statusStats)) {
        if (count > 0) {
            labels.push(statusLabels[status] || status);
            data.push(count);
            colors.push(statusColors[status] || '#6c757d');
        }
    }
    
    if (data.length === 0) {
        console.warn('没有有效的状态数据');
        return;
    }
    
    window.statusPieChart = new Chart(ctx, {
        type: 'doughnut',
        data: {
            labels: labels,
            datasets: [{
                data: data,
                backgroundColor: colors
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false
        }
    });
    
    console.log('状态饥图更新完毕');
}

function updateRecentExecutions(executions) {
    console.log('更新最近执行记录:', executions);
    
    const tbody = $('#recent-executions-table tbody');
    tbody.empty();
    
    if (!executions || !Array.isArray(executions) || executions.length === 0) {
        tbody.append('<tr><td colspan="4" class="text-center">暂无执行记录</td></tr>');
        console.log('没有执行记录数据');
        return;
    }
    
    executions.slice(0, 10).forEach(function(execution) {
        const statusBadge = getStatusBadge(execution.status);
        const taskName = execution.task_name || `任务 #${execution.task_id}`;
        const startTime = execution.started_at ? new Date(execution.started_at).toLocaleString() : '-';
        const duration = execution.duration ? formatDuration(execution.duration) : '-';
        
        tbody.append(`
            <tr>
                <td>${taskName}</td>
                <td>${statusBadge}</td>
                <td>${startTime}</td>
                <td>${duration}</td>
            </tr>
        `);
    });
    
    console.log(`最近执行记录更新完毕，显示${Math.min(executions.length, 10)}条记录`);
}

function updateUpcomingTasks(tasks) {
    console.log('更新即将执行任务:', tasks);
    
    const container = $('#upcoming-tasks');
    container.empty();
    
    if (!tasks || !Array.isArray(tasks) || tasks.length === 0) {
        container.append('<div class="text-muted">暂无即将执行的任务</div>');
        console.log('没有即将执行的任务');
        return;
    }
    
    tasks.forEach(function(task) {
        const nextRun = task.next_run_at ? new Date(task.next_run_at).toLocaleString() : '未设置';
        const taskType = task.task_type || 'unknown';
        const taskName = task.name || `任务 #${task.id}`;
        
        container.append(`
            <div class="d-flex justify-content-between align-items-center mb-2 p-2 border-start border-primary border-3">
                <div>
                    <div class="fw-bold">${taskName}</div>
                    <small class="text-muted">${nextRun}</small>
                </div>
                <span class="badge bg-primary">${taskType}</span>
            </div>
        `);
    });
    
    console.log(`即将执行任务更新完毕，显示${tasks.length}个任务`);
}

function getStatusBadge(status) {
    const badges = {
        'success': '<span class="badge bg-success">成功</span>',
        'failed': '<span class="badge bg-danger">失败</span>',
        'running': '<span class="badge bg-primary">运行中</span>',
        'pending': '<span class="badge bg-warning">等待中</span>',
        'cancelled': '<span class="badge bg-secondary">取消</span>'
    };
    return badges[status] || `<span class="badge bg-secondary">${status}</span>`;
}

function formatDuration(duration) {
    // 检查和转换输入类型
    let seconds;
    
    if (typeof duration === 'string') {
        // 如果是字符串，尝试转换为数字
        seconds = parseFloat(duration);
        if (isNaN(seconds)) {
            return duration; // 如果无法转换，直接返回原值
        }
    } else if (typeof duration === 'number') {
        seconds = duration;
    } else {
        return '-'; // 其他类型返回默认值
    }
    
    // 确保是有效数字
    if (isNaN(seconds) || seconds < 0) {
        return '-';
    }
    
    if (seconds < 60) {
        return seconds.toFixed(2) + '秒';
    } else if (seconds < 3600) {
        return Math.floor(seconds / 60) + '分' + Math.floor(seconds % 60) + '秒';
    } else {
        const hours = Math.floor(seconds / 3600);
        const minutes = Math.floor((seconds % 3600) / 60);
        return hours + '小时' + minutes + '分';
    }
}
</script>
{% endblock %}